package com.bk.circle;

import com.bk.AbstractList;

public class SingleCircleLinkedList<E> extends AbstractList<E> {
	private Node<E> first;

	private static class Node<E> {
		E elementE;
		Node<E> next;

		public Node(E elementE, Node<E> next) {
			this.elementE = elementE;
			this.next = next;
		}

		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append(elementE).append("_");
			sb.append(next.elementE);
			return sb.toString();
		}
	}

	private Node<E> node(int index) {
		rangeCheck(index);
		Node<E> node = first;
		for (int i = 0; i < index; i++) {
			node = node.next;
		}
		return node;
	}

	public void clear() {
		size = 0;
		first = null;

	}

	public int size() {

		return size;
	}

	public boolean isEmpty() {
		return size == 0;
	}

	public boolean contains(E element) {
		return false;
	}

	public E get(int index) {
		Node<E> node = this.node(index);
		return node.elementE;
	}

	public E set(int index, E element) {
		Node<E> node = this.node(index);
		E ele = node.elementE;
		node.elementE = element;
		return ele;
	}

	public void add(E element) {
		insert(size, element);
	}

	public void insert(int index, E element) {
		rangeCheck(index);
		if (index == 0) {
//			Node<E> prevfirst = first;
//			first = new Node<E>(element, null);
//			first.next = prevfirst;
//			Node<E> lastNode = (size == 0) ? first : node(size);
//			lastNode.next = first;
			Node<E> newNode = new Node<E>(element, first);
			Node<E> lastNode = (size == 0) ? newNode : node(size -1);
			lastNode.next = newNode;
			first = newNode;
			
		} else {
			Node<E> prev = this.node(index - 1);
			prev.next = new Node<E>(element, prev.next);
		}
		size++;
	}
/*
 * Node<E> lastNode;
			if (size == 0) {
				lastNode = first;
			} else {
				lastNode = node(size - 1);
			} 
			newNode.next = first;
			lastNode.next = newNode;
			first = newNode;
 * */
	public E remove(int index) {
		rangeCheck(index);
		Node<E> node = this.node(index);
		Node<E> prevNode;
		if (index == 0) {
			if (size == 1) {
				first = null;
			} else {
				prevNode = node(size - 1);
				prevNode.next = node.next;
				first = node.next;
			}
		} else {
			prevNode = node(index - 1);
			if (index == size - 1) {
				prevNode.next = first;
			} else {
				prevNode.next = node.next;
			}
		}

		size--;
		return node.elementE;
	}

	public int indexOf(E element) {
		Node<E> node = first;
		if (element == null) {
			for (int i = 0; i < size; i++) {
				if (node.elementE == null) {
					return i;
				}
			}
			return -1;
		} else {
			for (int i = 0; i < size; i++) {
				if (element.equals(node.elementE)) {
					return i;
				}
				node = node.next;
			}
			return -1;
		}
	}

	public String printStr() {
		Node<E> node = first;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {

			sb.append(node.toString());
			node = node.next;
			sb.append("，");
		}
		sb.append("\n");
		return sb.toString();
	}

}
